﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FangPage.Common;

namespace FangPage.Boxing
{
    public class Boxing
    {
        static float move = 100f;//边框宽度

        static float Max_X = 30000f;//X轴最大值

        static float Max_Y_Left = 4000f;//左Y轴最大值

        static float Max_Y_Right = 40f;//右Y轴最大值

        static int XscaleCount = 15;//X轴刻度线数量

        static int YscaleCount = 4;//Y轴刻度线数量

        static string Y_Left_Title = "应力";//左Y轴名称
        static string Y_Right_Title = "温度";//右Y轴名称
        static string X_Title = "位置";//X轴名称

        public byte[] DrawBoxing(int width, int height, List<FPObject> datas)
        {
            Bitmap image = new Bitmap(width, height);

            Graphics gph = Graphics.FromImage(image);

            //清空图片背景色
            gph.Clear(Color.White);

            try
            {
                //画图片的边框线
                gph.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);

                PointF cPt = new PointF(move, height / 2f);//中心点(坐标轴原点)   

                gph.DrawString("2021-12-21 21:12:30", new Font("宋体", 12, FontStyle.Bold), Brushes.Black, new PointF(width / 2f - 50, 12));//图表标题  

                DrawY_Left(gph, width, height, Max_Y_Left, YscaleCount);

                DrawY_Right(gph, width, height, Max_Y_Right, YscaleCount);

                DrawX_Bottom(gph, width, height, Max_X, XscaleCount);

                DrawX_Top(gph, width, height, Max_X, XscaleCount);

                gph.DrawLine(new Pen(Brushes.DarkGray, 2), cPt.X, cPt.Y, width - move, cPt.Y);//画出中轴线

                float X_Between = (width - move * 2f) / Max_X;//水平间距像素

                float Y_Left_Between = (image.Height / 2f - move) / Max_Y_Left; //左Y轴间距像素

                float Y_Right_Between = (image.Height / 2f - move) / Max_Y_Right;//右Y轴间距像素

                PointF[] arrDataPoint1 = new PointF[2];

                PointF[] arrDataPoint2 = new PointF[2];

                for (int i = 0; i < Max_X; i++)
                {
                    if (i < datas.Count)
                    {
                        float stressdata = Convert.ToSingle(datas[i]["stressdata"]);

                        PointF p = new PointF();
                        p.X = cPt.X + X_Between * i;
                        p.Y = cPt.Y - stressdata * Y_Left_Between;

                        arrDataPoint1[0] = arrDataPoint1[1];
                        arrDataPoint1[1] = p;

                        float temprdata = Convert.ToSingle(datas[i]["temprdata"]);
                        PointF p2 = new PointF();
                        p2.X = cPt.X + X_Between * i;
                        p2.Y = cPt.Y - temprdata * Y_Right_Between;

                        arrDataPoint2[0] = arrDataPoint2[1];
                        arrDataPoint2[1] = p2;

                        if (i > 0)
                        {
                            gph.DrawLine(Pens.Blue, arrDataPoint1[0].X, arrDataPoint1[0].Y, arrDataPoint1[1].X, arrDataPoint1[1].Y);
                            gph.DrawLine(Pens.Red, arrDataPoint2[0].X, arrDataPoint2[0].Y, arrDataPoint2[1].X, arrDataPoint2[1].Y);
                        }
                    }
                }

                //保存图片数据
                MemoryStream stream = new MemoryStream();
                image.Save(stream, ImageFormat.Gif);

                //输出图片流
                return stream.ToArray();
            }
            finally
            {
                gph.Dispose();
                image.Dispose();
            }
        }

        /// <summary>
        /// 画左边Y轴
        /// </summary>
        /// <param name="gph"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="maxY"></param>
        /// <param name="len"></param>
        public static void DrawY_Left(Graphics gph, int width, int height, float maxY, int len)
        {
            float LenY = height / 2f - move;

            //画出Y轴
            PointF py1 = new PointF(move, move);
            PointF py2 = new PointF(move, height - move);

            gph.DrawLine(new Pen(Brushes.Black, 2), py1, py2);

            StringFormat drawFormat = new StringFormat();
            drawFormat.Alignment = StringAlignment.Far;
            drawFormat.LineAlignment = StringAlignment.Center;

            //画Y轴正刻度
            for (int i = 0; i <= len; i++)
            {
                PointF px1 = new PointF(move, LenY * i / len + move);
                PointF px2 = new PointF(move + 4, LenY * i / len + move);

                gph.DrawLine(new Pen(Brushes.Black, 2), px1, px2);

                PointF _px2 = new PointF(width - move, LenY * i / len + move);

                gph.DrawLine(Pens.LightGray, px1, _px2);

                string sx = (maxY - maxY * i / len).ToString();

                gph.DrawString(sx, new Font("黑体", 10f), Brushes.Black, new PointF(move - 15, LenY * i / len + move), drawFormat);
            }

            //画Y轴负刻度
            for (int i = 1; i <= len; i++)
            {
                PointF px1 = new PointF(move, LenY * i / len + move + LenY);
                PointF px2 = new PointF(move + 4, LenY * i / len + move + LenY);

                gph.DrawLine(new Pen(Brushes.Black, 2), px1, px2);

                PointF _px2 = new PointF(width - move, LenY * i / len + move + LenY);

                gph.DrawLine(Pens.LightGray, px1, _px2);

                string sx = (maxY * i / len * -1).ToString();

                gph.DrawString(sx, new Font("黑体", 10f), Brushes.Black, new PointF(move - 15, LenY * i / len + move + LenY), drawFormat);
            }

            Pen pen = new Pen(Color.Black, 1);

            gph.DrawString(Y_Left_Title, new Font("宋体 ", 10f, FontStyle.Bold), Brushes.Black, new PointF(move - 15, move / 2f), drawFormat);
        }

        /// <summary>
        /// 画右边的Y轴
        /// </summary>
        /// <param name="gph"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="maxY"></param>
        /// <param name="len"></param>
        public static void DrawY_Right(Graphics gph, int width, int height, float maxY, int len)
        {
            float LenY = height / 2f - move;

            //画出Y轴
            PointF py1 = new PointF(width - move, move);
            PointF py2 = new PointF(width - move, height - move);

            gph.DrawLine(new Pen(Brushes.Black, 2), py1, py2);

            StringFormat drawFormat = new StringFormat();
            drawFormat.Alignment = StringAlignment.Near;
            drawFormat.LineAlignment = StringAlignment.Center;

            //画Y轴正刻度
            for (int i = 0; i <= len; i++)
            {
                PointF px1 = new PointF(width - move, LenY * i / len + move);
                PointF px2 = new PointF(width - move - 4, LenY * i / len + move);

                gph.DrawLine(new Pen(Brushes.Black, 2), px1, px2);

                string sx = (maxY - maxY * i / len).ToString();

                gph.DrawString(sx, new Font("黑体", 10f), Brushes.Black, new PointF(width - move + 15, LenY * i / len + move), drawFormat);
            }

            //画Y轴负刻度
            for (int i = 1; i <= len; i++)
            {
                PointF px1 = new PointF(width - move, LenY * i / len + move + LenY);
                PointF px2 = new PointF(width - move - 4, LenY * i / len + move + LenY);

                gph.DrawLine(new Pen(Brushes.Black, 2), px1, px2);

                string sx = (maxY * i / len * -1).ToString();

                gph.DrawString(sx, new Font("黑体", 10f), Brushes.Black, new PointF(width - move + 15, LenY * i / len + move + LenY), drawFormat);
            }

            Pen pen = new Pen(Color.Black, 1);

            gph.DrawString(Y_Right_Title, new Font("宋体 ", 10f, FontStyle.Bold), Brushes.Black, new PointF(width - move + 15, move / 2f));
        }

        /// <summary>
        /// 画底部X轴
        /// </summary>
        /// <param name="gph"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="maxY"></param>
        /// <param name="len"></param>
        public static void DrawX_Bottom(Graphics gph, int width, int height, float maxX, int len)
        {
            float LenX = width - 2 * move;

            //画出X轴
            PointF py1 = new PointF(move, height - move);
            PointF py2 = new PointF(width - move, height - move);

            gph.DrawLine(new Pen(Brushes.Black, 2), py1, py2);

            //画X轴正刻度
            for (int i = 0; i <= len; i++)
            {
                PointF px1 = new PointF(LenX * i / len + move, height - move);
                PointF px2 = new PointF(LenX * i / len + move, height - move - 4);

                gph.DrawLine(new Pen(Brushes.Black, 2), px1, px2);

                PointF _px2 = new PointF(LenX * i / len + move, move);

                gph.DrawLine(Pens.LightGray, px1, _px2);

                StringFormat drawFormat = new StringFormat();
                drawFormat.Alignment = StringAlignment.Far;
                drawFormat.LineAlignment = StringAlignment.Center;

                string sx = (maxX * i / len).ToString();

                if (i == 0)
                {
                    gph.DrawString(sx, new Font("黑体", 10f), Brushes.Black, new PointF(LenX * i / len + move + 8f, height - move / 1.2f), drawFormat);
                }
                else
                {
                    gph.DrawString(sx, new Font("黑体", 10f), Brushes.Black, new PointF(LenX * i / len + move + 16f, height - move / 1.2f), drawFormat);
                }
            }

            //X标题
            gph.DrawString(X_Title, new Font("宋体 ", 10f, FontStyle.Bold), Brushes.Black, new PointF(width / 2f - 5, height - move + 40f));
        }

        /// <summary>
        /// 画出顶部X轴
        /// </summary>
        /// <param name="gph"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="maxX"></param>
        /// <param name="len"></param>
        public static void DrawX_Top(Graphics gph, int width, int height, float maxX, int len)
        {
            float LenX = width - 2 * move;

            //画出X轴
            PointF py1 = new PointF(move, move);
            PointF py2 = new PointF(width - move, move);

            gph.DrawLine(new Pen(Brushes.Black, 2), py1, py2);

            //画X轴正刻度
            for (int i = 0; i <= len; i++)
            {
                PointF px1 = new PointF(LenX * i / len + move, move);
                PointF px2 = new PointF(LenX * i / len + move, move + 4);

                gph.DrawLine(new Pen(Brushes.Black, 2), px1, px2);
            }
        }
    }
}
